package com.xiaoshuidi.cloud.module.finance.controller.admin.finance;

import com.xiaoshuidi.cloud.framework.common.exception.ServiceException;
import com.xiaoshuidi.cloud.framework.common.pojo.CommonResult;
import com.xiaoshuidi.cloud.framework.common.pojo.PageResult;
import com.xiaoshuidi.cloud.framework.excel.core.util.ExcelUtils;
import com.xiaoshuidi.cloud.module.finance.controller.admin.finance.vo.flow.*;
import com.xiaoshuidi.cloud.module.finance.convert.finance.FinanceConvert;
import com.xiaoshuidi.cloud.module.finance.dal.dataobject.finance.FinanceMoneyFlowDO;
import com.xiaoshuidi.cloud.module.finance.enums.ErrorCodeConstants;
import com.xiaoshuidi.cloud.module.finance.service.finance.FinanceMoneyFlowService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

import static com.xiaoshuidi.cloud.framework.common.pojo.CommonResult.success;

@Tag(name = "管理后台 - 财务管理")
@RequestMapping("/finance/flow")
@RestController
public class FinanceMoneyFlowController {

    @Resource
    private FinanceMoneyFlowService financeMoneyFlowService;

    @GetMapping("/get")
    @Operation(summary = "获得流水明细信息")
    @Parameter(name = "id", description = "id", example = "1024")
    @Parameter(name = "sourceBizId", description = "业务id与id二选一", example = "1024")
    @Parameter(name = "sourceBizType", description = "业务类型RENT_ORDER(\"账单\"), ROOM_RESERVE(\"房源预定\"), ACCOUNT_RECHARGE(\"账户充值\"), OWNER_ORDER(\"业主合同\")", example = "1024")
//    @PreAuthorize("@ss.hasPermission('finance:flow:query')")
    public CommonResult<FinanceMoneyFlowRespVO> getApp(@RequestParam(value = "id", required = false) Long id, @RequestParam(value = "sourceBizId", required = false) String sourceBizId,
                                                       @RequestParam(value = "sourceBizType", required = false) String sourceBizType) {
        FinanceMoneyFlowDO financeMoneyFlowDO;
        if (id != null) {
            financeMoneyFlowDO = financeMoneyFlowService.getById(id);
        } else if (StringUtils.hasText(sourceBizId) && StringUtils.hasText(sourceBizType)) {
            financeMoneyFlowDO = financeMoneyFlowService.getBySourceBizIdAndSourceBizType(sourceBizId, sourceBizType);
        } else {
            throw new ServiceException(ErrorCodeConstants.FINANCE_MONEY_FLOW_NOT_EXISTS);
        }
        return success(FinanceConvert.INSTANCE.convert(financeMoneyFlowDO));
    }

    @GetMapping("/get-list")
    @Operation(summary = "获得流水明细信息列表")
    @Parameter(name = "sourceBizId", description = "业务id与id二选一", example = "1024")
    @Parameter(name = "sourceBizType", description = "业务类型RENT_ORDER(\"账单\"), ROOM_RESERVE(\"房源预定\"), " +
            "ACCOUNT_RECHARGE(\"账户充值\"), OWNER_ORDER(\"业主合同\")", example = "1024")
    public CommonResult<List<FinanceMoneyFlowRespVO>> getApp(@RequestParam(value = "sourceBizId", required = false) String sourceBizId,
                                                             @RequestParam(value = "sourceBizType", required = false) String sourceBizType) {
        return success(FinanceConvert.INSTANCE.convertList(financeMoneyFlowService.getListBySourceBizIdAndSourceBizType(sourceBizId, sourceBizType)));
    }

    /**
     * 交易流水分页
     *
     * @return
     */
    @GetMapping("/page")
    @Operation(summary = "获得流水列表")
    @PreAuthorize("@ss.hasPermission('finance:flow:query')")
    public CommonResult<FinanceMoneyFlowPageResult> getFinanceMoneyFlowPage(FinanceMoneyFlowPageReqVO reqVO) {
        PageResult<FinanceMoneyFlowDO> pageResult = financeMoneyFlowService.getFinanceMoneyFlowPage(reqVO);
        FinanceMoneyFlowPageResult result = financeMoneyFlowService.getFinanceMoneyFlowSummary(reqVO);
        PageResult<FinanceMoneyFlowRespVO> p = FinanceConvert.INSTANCE.convertToFinanceMoneyFlowPage(pageResult);
        result.setTotal(p.getTotal());
        result.setList(p.getList());
        return success(result);
    }

    /**
     * 流水勾核分页
     *
     * @return
     */
    @GetMapping("/confirm/page")
    @Operation(summary = "获得流水勾核列表")
    @PreAuthorize("@ss.hasPermission('finance:flow:confirm:query')")
    public CommonResult<FinanceMoneyFlowConfirmPageResult> getFinanceMoneyFlowConfirmPage(FinanceMoneyFlowPageReqVO reqVO) {
        PageResult<FinanceMoneyFlowDO> pageResult = financeMoneyFlowService.getConfirmFinanceMoneyFlowPage(reqVO);
        FinanceMoneyFlowConfirmPageResult result = financeMoneyFlowService.getFinanceMoneyFlowConfirmSummary(reqVO);
        PageResult<FinanceMoneyFlowRespVO> p = FinanceConvert.INSTANCE.convertToFinanceMoneyFlowPage(pageResult);
        result.setTotal(p.getTotal());
        result.setList(p.getList());
        return success(result);
    }

    /**
     * 交易流水
     *
     * @return
     */
    @GetMapping("/export")
    @Operation(summary = "流水明细导出")
    @PreAuthorize("@ss.hasPermission('finance:flow:export')")
    public void export(HttpServletResponse response, FinanceMoneyFlowPageReqVO reqVO) throws IOException {
        reqVO.setPageSize(100);
        PageResult<FinanceMoneyFlowDO> pageResult = financeMoneyFlowService.getFinanceMoneyFlowPage(reqVO);
        ExcelUtils.write(response, "流水明细.xlsx", "流水明细", FinanceMoneyFlowExcelVO.class, pageResult,
                FinanceConvert.INSTANCE::convertToFinanceMoneyFlowExcelList, (pageNo) -> {
                    reqVO.setPageNo(pageNo);
                    return financeMoneyFlowService.getFinanceMoneyFlowPage(reqVO);
                });
    }

    /**
     * 流水勾核
     *
     * @return
     */
    @PostMapping("/confirm/{id}")
    @Operation(summary = "流水勾核")
    @PreAuthorize("@ss.hasPermission('finance:flow:confirm')")
    public CommonResult<Void> confirm(@PathVariable Long id) {
        financeMoneyFlowService.confirm(id, new FinanceMoneyFlowConfirmReqVO());
        return CommonResult.success();
    }


    /**
     * 流水勾核退回
     *
     * @return
     */
    @PostMapping("/returnMoney/{id}")
    @Operation(summary = "流水勾核退回")
    @PreAuthorize("@ss.hasPermission('finance:flow:confirm')")
    public CommonResult<Void> returnMoney(@PathVariable Long id) {
        financeMoneyFlowService.returnMoney(id, new FinanceMoneyFlowConfirmReqVO());
        return CommonResult.success();
    }

    /**
     * 流水勾核退回
     *
     * @return
     */
    @PostMapping("/returnMoney")
    @Operation(summary = "流水勾核退回")
    @PreAuthorize("@ss.hasPermission('finance:flow:confirm')")
    public CommonResult<Void> returnMoney(@Validated({FinanceMoneyFlowConfirmReqVO.Reject.class})
                                          @RequestBody FinanceMoneyFlowConfirmReqVO vo) {
        financeMoneyFlowService.returnMoney(vo.getId(), vo);
        return CommonResult.success();
    }

    /**
     * 根据账单编号获取交易明细
     *
     * @return
     */
    @GetMapping("/confirm/get-flow")
    @Operation(summary = "流水勾核")
    public CommonResult<List<FinanceFlowMoneyVO>> getFlow(@RequestParam("orderNo") String orderNo) {
        return CommonResult.success(financeMoneyFlowService.getFlow(orderNo));
    }
}
